package org.inh.ld20.dangerousbrother.entity;

import org.inh.ld20.dangerousbrother.Animation;
import org.inh.ld20.dangerousbrother.DangerousBrother;
import org.inh.ld20.dangerousbrother.Level;

public class Entity {
	public static final double GRAVITY = 0.2;
	public static final double JUMP_MAGNITUDE = 4.0;
	
	/**
	 * x and y are in world coordinates
	 */
	public double x, y;
	public int width, height;
	public Entity follower, following;
	public Animation animation;
	public enum FacingDirection {
		LEFT(1),RIGHT(-1);
		public final int singularValue;
		private FacingDirection(int value) {
			singularValue = value;
		}
	};
	public FacingDirection facingDirection = FacingDirection.RIGHT;
	
	public double vy = GRAVITY;
	
	public Entity(Animation anim) {
		this.animation = anim;
		this.width = anim.getWidth();
		this.height = anim.getHeight();
	}
	
	public boolean tryMoveAbs(Level level, double newx, double newy) {
		return tryMove(level, newx - x, newy - y);
	}
	
	public boolean tryMove(Level level, double dx, double dy) {
		return tryMove(level, dx, dy, true);
	}
	
	private boolean tryMove(Level level, double dx, double dy, boolean moveFollower) {
		// check collision with the current Level
		if(x+dx < 0 || x+dx+width > DangerousBrother.GAME_WIDTH ||
				y+dy < 0 || y+dy+height > DangerousBrother.GAME_HEIGHT) {
			return false;
		}
		
		if(!level.canBeLocated(this, x+dx, y+dy))
			return false;
		
		x += dx;
		y += dy;
		return true;
	}
	
	public void gravity(Level level) {
		if(tryMove(level, 0, vy, false)) {
			vy += GRAVITY;
		} else {
			vy = GRAVITY;
		}
	}
	
	public void attemptJump() {
		if(vy == GRAVITY) {
			vy = -JUMP_MAGNITUDE;
		}
	}
	
	public boolean followedBy(Entity e) {
		return (follower != null && (follower == e || follower.followedBy(e))); 
	}
}
